#include <iostream>
#include "mysql.h"
#include <string>
#include <unistd.h>
#include "Util.hpp"

#define HOST "127.0.0.1"
#define USER "http_client"
#define PASSWD "12345678"
#define DB "http_sql"
#define PORT 3306

// id_text用的是mediumtext类型

class Sql_Query
{
private:
    MYSQL *connect = nullptr;
    bool quit = false;
    std::string body;
    int length = 0;

    std::string query;

    std::string html_prev = "<!DOCTYPE html><head><meta charset = \"utf-8\"></ head><body> ";
    std::string html_post = "</body></html>";

private:
    int SelectId()
    {
        std::string name = getenv("user");
        std::string sql_query = "select*from user where name=\'";
        sql_query += name;
        sql_query += "\'";

        mysql_query(connect, sql_query.c_str());
        MYSQL_RES *res = mysql_store_result(connect);
        MYSQL_ROW row = mysql_fetch_row(res);
        mysql_free_result(res);
        return atoi(row[0]);
    }

    void UserInsert(const std::string name, const std::string passwd)
    {
        std::string sql_query = "insert into user(name,password) values (\'";
        sql_query += name;
        sql_query += "\',\'";
        sql_query += passwd;
        sql_query += "\')";

        std::cerr << sql_query << std::endl;

        bool ret = mysql_query(connect, sql_query.c_str());
        if (!ret)
        {
            std::cerr << "insert user success" << std::endl;
            std::cout << "login was successful" << std::endl;
        }
        else
        {
            std::cout << "User name is occupied！" << std::endl;
        }
    }

public:
    Sql_Query()
    {
        connect = mysql_init(nullptr);
        MYSQL *msq_ret = mysql_real_connect(connect, HOST, USER, PASSWD, DB, PORT, nullptr, 0);
        mysql_set_character_set(connect, "utf8");
        if (msq_ret == nullptr)
        {
            std::cerr << "connect MySQL error!" << std::endl;
            quit = true;
        }
        std::cerr << "connect MySQL success!" << std::endl;
    }

    ~Sql_Query()
    {
        mysql_close(connect);
    }

    void GetBody()
    {
        length = atoi(getenv("Content-Length"));
        char ch = 0;
        while (length--)
        {
            read(0, &ch, 1);
            body.push_back(ch);
        }
    }

public:
    void SelectUser()
    {
        std::string name, passwd;

        Util::CutString(body, name, passwd, "&");
        name = name.substr(5);
        passwd = passwd.substr(9);
        Util::url_decode(name);

        std::cout << name << "---" << passwd << std::endl;
        std::string sql_query = "select*from user where name=\'";
        sql_query += name;
        sql_query += "\' and password=\'";
        sql_query += passwd;
        sql_query += "\'";

        std::cerr << sql_query << std::endl;

        mysql_query(connect, sql_query.c_str());
        MYSQL_RES *res = mysql_store_result(connect); // 查看有多少返回结果
        int num = mysql_num_rows(res);
        if (num == 1)
        {
            std::cout << "Login succeeded" << std::endl;
        }
        else
        {
            UserInsert(name, passwd);
        }
        mysql_free_result(res);
    }

    void ChangePasswd()
    {
        body = body.substr(7);
        std::string name = getenv("user");

        std::string sql_query = "update user set password=\'";
        sql_query += body;
        sql_query += "\' where name=\'";
        sql_query += name;
        sql_query += "\'";
        std::cerr << sql_query << std::endl;
        bool ret = mysql_query(connect, sql_query.c_str());
        if (!ret)
        {
            std::cout << "Modified successfully" << std::endl;
        }
        else
        {
            std::cout << "Modification failed！" << std::endl;
        }
    }

    void TextInsert() // post
    {
        std::string text_name;
        std::string text;
        Util::CutString(body, text_name, text, "&");
        text_name = text_name.substr(10);
        text = text.substr(8);
        Util::url_decode(text_name);
        Util::url_decode(text);

        int id = SelectId();

        std::string sql_query = "insert into id_text (id,article,name) values(\'";
        sql_query += std::to_string(id);
        sql_query += "\',\'";
        sql_query += text;
        sql_query += "\',\'";
        sql_query += text_name;
        sql_query += "\')";
        std::cerr << sql_query << std::endl;

        bool ret = mysql_query(connect, sql_query.c_str());
        if (!ret)
        {
            std::cout << "Saved successfully" << std::endl;
        }
        else
        {
            std::cout << "Saved failed！" << std::endl;
        }
    }

    void SelectText() // post
    {
        std::string name = body.substr(12);
        Util::url_decode(name);
        std::string sql_query = "select article from id_text where name=\'";
        sql_query += name;
        sql_query += "\'";
        std::cerr << sql_query << std::endl;

        bool ret = mysql_query(connect, sql_query.c_str());
        MYSQL_RES *res = mysql_store_result(connect);

        MYSQL_ROW row = mysql_fetch_row(res);
        std::string rep_body = row[0];

        mysql_query(connect, sql_query.c_str());
        res = mysql_store_result(connect);
        mysql_free_result(res);
        html_prev += rep_body;
        html_prev += html_post;
        std::cout << html_prev << std::endl;
    }

    // GET方法
    void DropUser()
    {
        std::string id = std::to_string(SelectId());
        // 删除账户
        std::string sql_query = "delete from user where id=\'";
        sql_query += id;
        sql_query += "\'";
        bool ret = mysql_query(connect, sql_query.c_str());
        // 删除对应文档
        sql_query = "delete from id_text where id=\'";
        sql_query += id;
        sql_query += "\'";
        std::cerr<<sql_query<<std::endl;
        ret = mysql_query(connect, sql_query.c_str());
        if (!ret)
        {
            std::cout << "Delete succeeded" << std::endl;
        }
        else
        {
            std::cout << "Delete failed！" << std::endl;
        }
    }

    void TextDrop()
    {
        std::string query = getenv("QUERY_STRING");
        std::string text_name;
        std::string tmp;
        Util::CutString(query, text_name, tmp, "&");
        text_name = text_name.substr(10);
        Util::url_decode(text_name);

        std::string sql_query = "delete from id_text where name=\'";
        sql_query += text_name; // 名字不可重复，直接查即可
        sql_query += "\'";
        std::cerr << sql_query << std::endl;

        bool ret = mysql_query(connect, sql_query.c_str());
        if (!ret)
        {
            std::cout << "Delete succeeded" << std::endl;
        }
        else
        {
            std::cout << "Delete failed！" << std::endl;
        }
    }

    bool IsQuit()
    {
        return quit;
    }

    std::string &Body()
    {
        return body;
    }

    std::string &Query()
    {
        return query;
    }
};

int main()
{
    Sql_Query sql;
    if (sql.IsQuit())
    {
        return 1;
    }

    std::string method = getenv("METHOD");

    if (method == "GET")
    {
        std::string &query = sql.Query();
        query = getenv("QUERY_STRING");
        if (query.find("drop") != std::string::npos)
        {
            query = query.substr(5);
            sql.TextDrop();
        }
        else if (query.find("delete") != std::string::npos)
        {
            sql.DropUser();
        }
    }
    else if (method == "POST")
    {
        sql.GetBody();
        std::cerr << sql.Body() << std::endl;
        std::string head = sql.Body().substr(0, 15); // 前15个肯定比表单的名长
        if (head.find("passwd") == 0)
        {
            sql.ChangePasswd();
        }
        else if (head.find("text_name") == 0)
        {
            sql.TextInsert();
        }
        else if (head.find("user") == 0)
        {
            sql.SelectUser();
        }
        else if (head.find("search_name") == 0)
        {
            sql.SelectText();
        }
    }
    return 0;
}